Я попытался сделать это с помощью cat
, а затем после ввода второго файла я добавил | head -$line | tail -1
, но он не работает, потому что он сначала выполняет cat
.
Любые идеи? Мне нужно сделать это с помощью cat
или что-то еще.
Я попытался сделать это с помощью cat
, а затем после ввода второго файла я добавил | head -$line | tail -1
, но он не работает, потому что он сначала выполняет cat
.
Любые идеи? Мне нужно сделать это с помощью cat
или что-то еще.
Я бы использовал sed
для этого задания:
line=3
sed -e "${line}r file2" file1
Если вы хотите перезаписать file1
и у вас есть GNU sed
, добавьте параметр -i
. В противном случае, напишите во временный файл, а затем скопируйте/переместите временный файл поверх оригинала, очистите его по необходимости (это тег trap
ниже). Примечание: копирование временного файла сохраняет ссылки; перемещение не (но более быстрое, особенно если файл большой).
line=3
tmp="./sed.$$"
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
sed -e "${line}r file2" file1 > $tmp
cp $tmp file1
rm -f $tmp
trap 0
Просто для удовольствия, и только потому, что мы все любим ed
, стандартный редактор, здесь ed
. Он очень эффективен (ed
является подлинным текстовым редактором)!
ed -s file2 <<< $'3r file1\nw'
Если номер строки сохраняется в переменной line
, то:
ed -s file2 <<< "${line}r file1"$'\nw'
Просто, чтобы угодить Заку, здесь одна версия с меньшим багизмом, если вам не нравится bash (лично мне не нравятся трубы и подоболочки, я предпочитаю herestrings, но эй, как я сказал, что только угодить Заку):
printf "%s\n" "${line}r file1" w | ed -s file2
или (чтобы угодить Сорпигалу):
printf "%dr %s\nw" "$line" file1 | ed -s file2
Как упоминает Джонатан Леффлер в комментарии, и если вы намереваетесь использовать этот метод в script, используйте heredoc (он обычно самый эффективный):
ed -s file2 <<EOF
${line}r file1
w
EOF
Надеюсь, это поможет!
P.S. Не стесняйтесь оставлять комментарий, если вы чувствуете, что вам нужно выразить себя о том, как управлять стандартным редактором ed
.
cat file1 >>file2
добавит содержимое файла1 в файл2.
cat file1 file2
будет конкатенация файлов1 и file2 и отправки вывода на терминал.
cat file1 file2 >file3
создаст или переит файл3 с конкатенацией файлов file1 и file2
cat file1 file2 >>file3
добавит конкатенацию file1 и file2 в конец файла3.
Edit
Для транкинга файла2 перед добавлением файла1:
sed -e '11,$d' -i file2 && cat file1 >>file2
или для создания файла с 500 строками:
n=$((500-$(wc -l <file1)))
sed -e "1,${n}d" -i file2 && cat file1 >>file2
Много способов сделать это, но мне нравится выбирать способ, который включает в себя создание инструментов.
Сначала установите тестовую среду
rm -rf /tmp/test
mkdir /tmp/test
printf '%s\n' {0..9} > /tmp/test/f1
printf '%s\n' {one,two,three,four,five,six,seven,eight,nine,ten} > /tmp/test/f2
Теперь давайте сделаем инструмент, и в этом первом проходе мы будем плохо его реализовывать.
# insert contents of file $1 into file $2 at line $3
insert_at () { insert="$1" ; into="$2" ; at="$3" ; { head -n $at "$into" ; ((at++)) ; cat "$insert" ; tail -n +$at "$into" ; } ; }
Затем запустите инструмент, чтобы увидеть удивительные результаты.
$ insert_at /tmp/test/f1 /tmp/test/f2 5
Но подождите, результат на stdout! Как насчет перезаписи оригинала? Нет проблем, мы можем сделать еще один инструмент для этого.
insert_at_replace () { tmp=$(mktemp) ; insert_at "[email protected]" > "$tmp" ; mv "$tmp" "$2" ; }
И запустите его
$ insert_at_replace /tmp/test/f1 /tmp/test/f2 5
$ cat /tmp/test/f2
"Ваша реализация отстой!"
Я знаю, но это красота создания простых инструментов. Позвольте заменить insert_at
на версию sed.
insert_at () { insert="$1" ; into="$2" ; at="$3" ; sed -e "${at}r ${insert}" "$into" ; }
И insert_at_replace
продолжает работать (конечно). Реализация insert_at_replace
также может быть изменена, чтобы быть менее глючной, но я оставлю это как упражнение для читателя.
Мне нравится делать это с head
и tail
если вы не возражаете управлять новым файлом:
head -n 16 file1 > file3 &&
cat file2 >> file3 &&
tail -n+56 file1 >> file3
Вы можете свернуть это в одну строку, если хотите. Затем, если вам действительно нужно перезаписать файл file1, выполните:
mv file3 file1
(опционально&&
между командами).
Заметки:
head -n 16 file1
означает первые 16 строк file1tail -n+56 file1
означает file1, начиная со строки 56 и заканчиваяhead
и " tail
а затем попробовать магическую команду " sed
.