Как создать несколько каталогов на основе имен файлов и изменить имена файлов в Linux?

Предположим, что вы хотите сказать:

У меня есть длинный файл с несколькими счетами. Каждый счет начинается с текста 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
0
14.11.2020, 18:53
1 ответ

Проверить:

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
2
18.03.2021, 22:49

Теги

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