Как добавить порядковые номера, скажем, 1,2,3 и т. Д. К каждому имени файла, а также для каждой строки содержимого файла в каталоге? - PullRequest
0 голосов
/ 08 апреля 2019

Я хочу добавить порядковый номер для каждого файла и его содержимого в каталоге. Порядковый номер должен начинаться с имени файла, и для каждой строки его содержимого должен быть указан одинаковый номер. Таким образом, последовательные номера должны генерироваться для всех файлов (для имен и их содержимого) в подпапках каталога.

Я пытался использовать функции maxdepth, rename, print как часть. но выдает ошибку, говоря, что «-maxdepth» - недопустимый параметр.

У меня уже есть часть кода (для печати имен и содержимого текстовых файлов в каталоге), и к ней должна быть добавлена ​​эта логика.

#!bin/bash
cd home/TESTING
for file in home/TESTING;
do
find home/TESTING/ -type f -name *.txt -exec basename {} ';' -exec cat {} \;
done

P.s - печать, переименование, maxdepth не работают

Если имя первого файла - File1.txt, а его содержимое упоминается как «Louis», то для имени файла должен быть вывод 1File1.txt, а содержимое - «1Louis». То же самое следует заменить на 2 для второго файла. Таким образом, он должен пройти через все подпапки в каталоге и распечатать соответственно. У меня уже есть часть кода, и к ней должна быть добавлена ​​эта логика.

1 Ответ

2 голосов
/ 09 апреля 2019

Должно быть отказоустойчиво, если вы выполняете CD в скрипте. Вы можете выполнить команду в неправильном каталоге, если вы этого не сделаете.

В вашей попытке вывод будет таким же, даже без цикла for, поскольку for file in home/TESTING только передает home/TESTING в качестве аргумента for, поэтому он запускается только один раз. В случае for file in home/TESTING/* это могло бы случиться иначе как.

Я использовал find без --maxdepth, поэтому он будет искать также все подкаталоги для файлов *.txt. Если вы хотите, чтобы только текущий каталог $(find /home/TESTING/* -type f -name "*.txt") мог быть заменен на $(ls *.txt), пока у вас нет каталога, оканчивающегося на .txt, проблем не будет.

#!/bin/bash

# try cd to directory, do things upon success.
if cd /home/TESTING ;then
      # set sequence number
      let "x = 1"

      # pass every file to for that find matching, sub directories will be also as there is no maxdeapth.
      for file in $(find /home/TESTING/* -type f -name "*.txt") ; do

            # print sequence number, and base file name, processed by variable substitution. 
            # basename can be used as well but this is bash built in.
            echo "${x}${file##*/}"

            # print file content, and put sequence number before each line with stream editor.
            sed 's#^#'"${x}"'#g' ${file}

            # increase sequence number with one.
            let "x++"
      done

      # unset sequence number
      unset 'x'
else
      # print error on stderr
      echo 'cd to /home/TESTING directory is failed' >&2
fi

Замена переменной:

Более того, я выбрал только эти 4, поскольку они похожи.

${var#pattern} - Использовать значение var после удаления текста, соответствующего шаблону слева

${var##pattern} - То же, что и выше, но вместо самого короткого удаляется самый длинный соответствующий элемент

${var%pattern} - Использовать значение var после удаления текста, соответствующего шаблону справа

${var%%pattern} - То же, что и выше, но вместо самого короткого удаляется самый длинный соответствующий элемент

Так что ${file##*/} возьмет переменную $ file и сбросит каждый символ * перед последним ## косой чертой /. Значение переменной $file не может быть изменено, поэтому оно по-прежнему содержит путь и имя файла.

sed 's#^#'"${x}"'#g' ${file} sed - это потоковый редактор, есть целые книги о его использовании, для этого конкретного. Обычно он помещается в одинарные кавычки, поэтому 's#^#1#g' добавляет 1 начало каждой строки в файле. s - это подстановка, ^ - начало файла, 1 - текст, g - Глобальный, если вы не поместите туда данный первый мах, будет затронут. # - это разделитель, он может быть и другим, например, /. Я блокирую одинарную кавычку, чтобы разрешить использование переменной, и снова открываю одинарную кавычку.

Если вы хотите заменить текст с .txt на .php, вы можете использовать sed 's#\.txt#\.php#g' file, ., имеющие специальное значение, он может заменить любой одиночный символ, поэтому его необходимо экранировать \, чтобы использовать это как текст. иначе будет сопоставлено не только file.txt, но и file1txt.

Он может быть передан по конвейеру, вам не нужно указывать имя файла в этом случае, иначе вы должны указать хотя бы одно имя файла, в нашем случае это была переменная ${file}, которая содержит имя файла. Как я уже упоминал, подстановка переменных не является изменением значения переменной, поэтому она по-прежнему содержит имя файла с путем.

...