Предположим, что вы хотите сказать:
У меня есть длинный файл с несколькими счетами. Каждый счет начинается с текста 70 spaces and a 1
. Мне нужно вставить новый контент за 9 строк до этого для каждого счета
Тогда вам нужно накопить 10 строк. Когда текущая строка соответствует началу счета-фактуры , вставьте в первую строку новый текст.
На практике это приводит к тому, что:
sed -e '1{N;N;N;N;N;N;N;N}' -e 'N;l;/\n \{70\}1$/{iNew content here' -e 'P};P;D' file
Или, в полной форме (комментарии не работают в некоторых реализациях sed):
sed '1{ # (only) on the first line
N;N;N;N;N;N;N;N # accumulate 9 lines (first one plus 8 more).
}
N # On every line,also accumulate that line
/\n \{70\}1$/{ # If buffer ends ($) in 70 spaces and a "1"
i\
New content added here # insert the content of this line at
# the start of the buffer (10 lines above).
P # and then print it.
}
P;D # close the N cycle above by
# printing and deleting one line
' file # On the selected file.
Решение awk
может использовать преимущества установки RS на строку, которая отмечает начало счета. В этом случае установка FS на символ новой строки разбивает каждую строку на поле, а $ (NF -9 )будет ссылаться на строку на 9 строк выше:
awk -v ln=9 '
( NF < ln ){ print; next }; # not enought fields?
# include
{ $(NF-ln) = "New Text to include" newln $(NF-ln);
print # and print
};
BEGIN{ breakln = sprintf("%71s",1); # 70 spaces and a 1
newln = sprintf("\n"); # a newline
RS = breakln newln; # set the Record Separator
FS = "\n"; # set the Field separator
OFS = FS; # print what got removed
ORS = RS # print what got removed
}
' file
Или, альтернативно, (решение оболочки/awk):
breakln="$(printf '%71s' 1)";
newl=$'\n';
awk ' (NF<ln){print;next};
{ $(NF-ln)="New Text to include\n"$(NF-ln); print}' \
ln=10 \
RS="$breakln$newl" \
FS="$newl" \
OFS="$newl" \
ORS="$breakln$mewl" \
file
Проверить:
for file in./*; do
echo mkdir -p "${file%.*}"/cuffcompare/ && \
echo mv "$file" "$_"soft.track
done
к вкладышу:
for file in./*; do echo mkdir -p "${file%.*}"/cuffcompare/ && echo mv "$file" "$_"soft.track; done
Примечание. :Удалите echo
выше, если вас устраивает результат сухого прогона -.
${file%.*}
удаляет самый короткий совпадающий суффикс из имени файла. поэтому здесь вырезается .track
с конца имени файла. известный параметр -расширение
$_
заменяет последний аргумент предыдущей команды (см. Специальные параметры оболочки); который расширяется до "${file%.*}"/cuffcompare/
;
поэтому mkdir
создает каталоги(-p
используется для создания родительских каталогов, если они не существуют )структура ниже для каждого найденного файла;
└── file_2001to3000
└── cuffcompare
, затем mv
перемещает и переименовывает файл в соответствующий каталог с именем soft.tarck
:
└── file_2001to3000
└── cuffcompare
└── soft.track