Я читаю файл построчно, редактирую каждую строку и сохраняю эти строки в отдельном файле.
while read -r line
do
newline=$(echo $line | sed -r 's/\</\n/g' | sort | tr '\n' ' ')
echo "$newline" >> newfile
done < "$filename"
Но я хочу заменить оригинальные линии относительно $filename
новыми линиями. Я читал, что я мог бы использовать cat filename... | xargs -n1 command
или sed -i ...
, но до сих пор мои тропы не увенчались успехом.
Вот пример ввода:
1.e4 e5 2.Nf3 Nc6 3.
1.d4 d5 2.e4 dxe4 3.
1.e4 e5 2.Nf3 Nf6 3.
и вот ожидаемый результат:
1. 2. 3. e4 e5 Nc6 Nf3
1. 2. 3. d4 d5 dxe4 e4
1. 2. 3. e4 e5 Nf3 Nf6
решение1
Вы можете использовать sponge
, как указано вПрограмма, которая может буферизовать stdin или файл. Вы можете передать ему весь цикл, таким же образом, как на него перенаправляется ввод:
while read -r line ; do
echo "$line" | sed -r 's/\</\n/g' | sort | tr '\n' ' ' ;
echo
done < filename | sponge filename
С помощью Perl то же самое можно сделать следующим образом (количество пробелов отличается):
perl -Mlocale -i -lne 'print join " ", sort split/(?<=\.)| /' filename
решение2
awkподход:
awk 'BEGIN{IGNORECASE=1;}{ gsub(/\./,". ", $0); split($0, w, " ");
asort(w);l=""; for(i in w) {l=l" "w[i]} print l}' file
Выход:
1. 2. 3. e4 e5 Nc6 Nf3
1. 2. 3. d4 d5 dxe4 e4
1. 2. 3. e4 e5 Nf3 Nf6
ИГНОРИРОВАТЬРЕГИСТРможно задать в командной строке или вНАЧИНАТЬправило
split($0, w, " ");
- разбивает строку на отдельные слова
asort(w);
- сортирует значения массива (слова)
for(i in w) {l=l" "w[i]}
- объединение отсортированных слов в одну строку