Как объединить строки, начинающиеся с одинаковых элементов в текстовом файле
У меня есть текстовый файл, содержащий несколько тысяч строк следующим образом:
Файл:
abc: bla1 bla1 bla1...
cde: bla bla bla...
ghk: bla1 bla1 bla1...
lmn: bla bla bla...
abc: bla2 bla2 bla2...
bcd: bla bla bla...
ghk: bla2 bla2 bla2...
xyz: bla bla bla...
Я хочу объединить все строки, которые начинаются с одинаковых элементов (как 1 and 5, 3 and 7
) так что у меня есть новый текстовый файл, как это:
Новый файл:
abc: bla1 bla1 bla1... * abc: bla2 bla2 bla2...
cde: bla bla bla...
ghk: bla1 bla1 bla1... * ghk: bla2 bla2 bla2...
lmn: bla bla bla...
bcd: bla bla bla...
xyz: bla bla bla...
Интересно, возможно ли это решить с помощью regex
и / или grep
и если да, то как я могу это решить?
Я хорошо знаком с grep
потому что я на TextWrangler, но также хорошо с другими текстовыми редакторами.
Помощь высоко ценится.
3 ответа
Если порядок не имеет значения, я предлагаю сначала отсортировать текст. Это будет место
abc: ...
abc: ...
рядом друг с другом. Затем вы выполните это регулярное выражение через несколько проходов:
Search:
^(\w+): (.*)\n\1:
Replace:
\1: \2
Result:
abc: bla1 bla1 bla1... bla2 bla2 bla2...
bcd: bla bla bla...
cde: bla bla bla...
ghk: bla1 bla1 bla1... bla2 bla2 bla2...
lmn: bla bla bla...
xyz: bla bla bla...
Если порядок имеет значение, то это регулярное выражение можно выполнить несколько раз:
Search:
^(\w+): (.*)\n((?:(?!\1).*\n)+)\1: (.*\n)
Replace:
\1: \2 \4\3
Result (1st pass):
abc: bla1 bla1 bla1... bla2 bla2 bla2...
cde: bla bla bla...
ghk: bla1 bla1 bla1...
lmn: bla bla bla...
bcd: bla bla bla...
ghk: bla2 bla2 bla2...
xyz: bla bla bla...
Result (2nd pass):
abc: bla1 bla1 bla1... bla2 bla2 bla2...
cde: bla bla bla...
ghk: bla1 bla1 bla1... bla2 bla2 bla2...
lmn: bla bla bla...
bcd: bla bla bla...
xyz: bla bla bla...
С GNU Bash. Если порядок не имеет значения.
declare -A A # declare associative array A
# fill array
while read I L; do
[ ${#A[$I]} -gt 0 ] && A[$I]+=" * $L"
[ ${#A[$I]} -eq 0 ] && A[$I]+=" $L"
done < filename
# print array
for J in "${!A[@]}"; do echo "$J${A[$J]}"; done
Выход:
xyz: bla bla bla...
lmn: bla bla bla...
abc: bla1 bla1 bla1... * bla2 bla2 bla2...
ghk: bla1 bla1 bla1... * bla2 bla2 bla2...
bcd: bla bla bla...
cde: bla bla bla...
Если вы можете использовать awk
, это должно работать:
awk '{a[$1]=a[$1]?a[$1]"* "$0:$0} END {for (i in a) print a[i]}' file
ghk: bla1 bla1 bla1... * ghk: bla2 bla2 bla2...
lmn: bla bla bla...
cde: bla bla bla...
xyz: bla bla bla...
bcd: bla bla bla...
abc: bla1 bla1 bla1... * abc: bla2 bla2 bla2..
,