Добавление префикса и добавление блоков текста к списку файлов

Необходимо включить extglob:

#!/bin/bash
shopt -s extglob
cat ~/my/+(a|b)/doc

+() расширенный шаблон, только распознан когда extglob включен. По умолчанию extglob идет в интерактивных оболочках и прочь в неинтерактивных оболочках.

5
13.04.2017, 15:36
4 ответа

Как насчет (принятие Вашей оболочки имеет замену процесса):

for file in "${filelist[@]}"; do
    cat <(printf "%s" "$prefix") "$file" <(printf "%s" "$suffix") > "$file"_$$\ 
     && mv "$file"_$$ "$file"
done

или, лучше, в (непротестированном) Perl:

perl -MTie::File -e '
    @ARGV//=<STDIN>;
    chomp(@ARGV);
    for(@ARGV){
        tie @lines,"Tie::File",$_;
        @lines=($ENV{prefix} @lines $ENV{suffix})
    }' "${filelist[@]}"

Для альтернативного подхода, если префикс и суффикс фиксируются, видят следующий вопрос (который также, оказывается, о TEX (La) :)):

2
27.01.2020, 20:38
  • 1
    Привет Joseph. Спасибо за предложения. Последний действительно походит на хороший простой способ приблизиться к проблеме. Большой –  Faheem Mitha 25.01.2014, 00:25
  • 2
    @FaheemMitha. Сообщите нам, как вещи удаются... –  Joseph R. 25.01.2014, 00:30
  • 3
    , я нашел Вас, связывается с "extractig и копирование частей..." более полезных. вышеупомянутое –   25.01.2014, 00:43

С zsh:

zmodload zsh/mapfile
for i ($filelist) mapfile[$i]="$prefix
$mapfile[$i]$suffix
"

С ksh93 или bash (или zsh):

for file in "${filelist[@]}"; do
  {
    rm -- "$file" && {
      printf '%s\n' "$prefix"
      cat
      printf '%s\n' "$suffix"
    } > "$file"
  } < "$file"
done
2
27.01.2020, 20:38

Вот несколько вариантов, ни один из которых не использует sed. Я нахожу что в целом, пытаясь добраться sed играть по правилам с внешними переменными редко стоит усилия.

Shell

for file in "${filelist[@]}"; do 
  tmp=$(mktemp); 
  printf "%s\n%s\n%s\n" "$prefix" $(cat "$file") "$suffix" > "$tmp" && 
  mv "$tmp" "$file"; 
done

Perl/Shell

for file in "${filelist[@]}"; do 
  tmp=$(mktemp); 
  perl -lpe 'BEGIN{print $ENV{prefix}}END{print $ENV{suffix}}' $file 
  mv "$tmp" "$file"; 
done

Чистый Perl

Этот имеет преимущество не доверия внешним модулям:

perl -le 'foreach (@ARGV){
           open($f,"+<","$_"); @a=<$f>; 
           print $f "$ENV{suffix}\n@a$ENV{prefix}"
          }' "${filelist[@]}"

Примечание:

Переменные должны быть экспортированы для решений для Perl работать, иначе, они не будут доступны в %ENV хеш.

1
27.01.2020, 20:38

Случай подобен этому: Добавление строки, содержащей символ ESC с sed

Я предлагаю тот же (адаптированный) ответ:

for file in "${filelist[@]}"; do
  sed -i "1i\\
$(echo -E "$prefix" | sed -e 's/\\/\\\\/g' | sed -e '$! s/$/\\/')" "$file" &&
  echo "$suffix" >> "$file"
done

sed команда i требует, чтобы каждая строка кроме последнего была завершена с обратной косой чертой (это отсутствовало в отнесенном ответе). Кроме того, обратные косые черты должны быть удвоены, таким образом, sed не попытается интерпретировать их. echo производит содержание переменной $prefix. Затем в конвейере, sed команда удваивает обратные косые черты. Второе sed команда добавляет обратные косые черты в конце каждой строки кроме последнего.

ОТРЕДАКТИРУЙТЕ Как sed программа $! s/$/\\/ работы:

Во-первых, адрес $ средства выполнить команду, которая следует последняя строка. $! инвертирует это, таким образом, команда будет выполняться на всех строках кроме последнего.

Затем s/// команда делает замену. Это заменит пустой строкой в конце строки, обозначенной $, с обратной косой чертой. Но обратная косая черта является специальным символом, таким образом, мы должны выйти из нее с другой обратной косой чертой для sed считать его правильно.

1
27.01.2020, 20:38
  • 1
    Привет Angus, спасибо за полезный ответ. К сожалению, обратные косые черты в концах строк появляется в окончательном результате. Действительно ли возможно подавить это? Кроме того, могли Вы ссылка некоторая sed документация это (a) i требует, чтобы каждая строка кроме последнего была завершена с обратной косой чертой и (b), что обратные косые черты должны быть удвоены? Наконец, если Вы вдаетесь в немного большее количество подробностей о как sed -e '$! s/$/\\/' работы, которые были бы полезны. –  Faheem Mitha 25.01.2014, 14:26
  • 2
    (a)-> gnu.org/software/sed/manual/html_node / …, (b)-> на той же странице, см. документацию для a\ . (c) видят отредактированный ответ. –  angus 25.01.2014, 21:10
  • 3
    Привет Angus. Спасибо за ссылки. Они могли обоснованно быть в вопросе, я думаю. Однако я не вижу изменения в коде (если я не пропускаю что-то). Как можно избавиться от дополнительных обратных косых черт? –  Faheem Mitha 25.01.2014, 21:34
  • 4
    я не могу воспроизвести проблему. Нет дополнительных обратных косых черт в выводе, когда я запускаю скрипт точно, как записано. Возможно, Вы не используете GNU sed? –  angus 25.01.2014, 21:49
  • 5
    sed --version GNU sed version 4.2.1. Какую версию Вы используете? В любом случае, нечетный. Я проверю снова в случае, если я сделал ошибку. –  Faheem Mitha 25.01.2014, 21:53

Теги

Похожие вопросы