Читать файл построчно, затем обрабатывать как другую переменную - PullRequest
2 голосов
/ 18 июня 2019

Я создал текстовый файл со списком имен файлов, как показано ниже

022694-39.tar
022694-39.tar.2017-05-30_13:56:33.OLD
022694-39.tar.2017-07-04_09:22:04.OLD
022739-06.tar
022867-28.tar
022867-28.tar.2018-07-18_11:59:19.OLD
022932-33.tar

Я пытаюсь прочитать файл построчно, а затем удалить что-либо после .tar с помощью awkи используйте его для создания папки, если она не существует.

Затем планируется скопировать исходный файл в новую папку с оригинальным полным именем, сохраненным в $ LINE.

$QNAP= "Path to storage"
$LOG_DIR/$NOVA_TAR_LIST= "Path to text file containing file names"
while read -r LINE; do
    CURNT_JOB_STRIPED="$LINE | `awk -F ".tar" '{print $1}'`"
    if [ ! -d "$QNAP/$CURNT_JOB_STRIPED" ]
        then
        echo "Folder $QNAP/$CURNT_JOB_STRIPED doesn't exist."
        #mkdir "$QNAP/$CURNT_JOB_STRIPED"
    fi
done <"$LOG_DIR/$NOVA_TAR_LIST"

К сожалению, это похоже на попытку объединить все имена файлов при попытке создать каталоги, а не делать их по одному, и я получаю вывод File name too long

:

......951267-21\n951267-21\n961075-07\n961148-13\n961520-20\n971333-21\n981325-22\n981325-22\n981743-40\n999111-99\n999999-04g\n999999-44': File name too long

Извинения, если это тривиально, немного новичка ...

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Проблема с линией CURNT_JOB_STRIPED="$LINE | `awk -F ".tar" '{print $1}'`".

`command` является устаревшим синтаксисом, вместо него следует использовать $(command).

$LINE переменная должна быть напечатана, чтобы awk мог получить ее значение через канал.

Если вы запускаете все это в субоболочке ($(command)), вы можете присвоить вывод переменной: var=$(date)

Безопаснее помещать переменные в ${}, поэтому при наличии окружающего текста вы не получите неожиданных результатов.

Это должно работать: CURNT_JOB_STRIPED=$(echo "${LINE}" | awk -F '.tar' '{print $1}')


С помощью подстановки переменных это может быть достигнуто с помощью более эффективного кода, а также, как мне кажется, его легко читать.

Подстановка переменной не приводит к изменению переменной ${LINE}, поэтому ее можно использовать позже как переменную с полным именем файла без изменений, в то время как ${LINE%.tar*} вырезает последний текст .tar из значения переменной и с * что-либо после что.

while read -r LINE; do
        if [ ! -d "${QNAP}/${LINE%.tar*}" ]
        then
                echo "Folder ${QNAP}/${LINE%.tar*} doesn't exist."
                #mkdir "${QNAP}/${LINE%.tar*}"
        fi
done <"${LOG_DIR}/${NOVA_TAR_LIST}"

Таким образом, вы не сохраняете имя каталога как переменную, а ${LINE} сохраняет только имя файла. Если вам это нужно в переменную, вы можете сделать это легко: var="${LINE%.tar*}"


Замена переменных:

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

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

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

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

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

1 голос
/ 18 июня 2019

Попробуйте изменить ваш скрипт следующим образом:

CURNT_JOB_STRIPED=$(echo "${LINE}" | awk -F ".tar" '{print $1}')

Вы должны использовать $(...) для подстановки команд. Кроме того, вы должны вывести переменную LINE, чтобы оболочка не интерпретировала свое значение как команду, а вместо этого передавала ее следующей команде канала (в качестве ввода). Наконец, вы должны удалить обратные галочки из выражения awk (это устаревший синтаксис для подстановки команд), поскольку вы хотите получить результат от команд конвейера.

Для получения дополнительной информации посмотрите http://tldp.org/LDP/abs/html/commandsub.html

В качестве альтернативы, и гораздо менее читаемый (ни с более высокой производительностью, то есть просто как «любопытство»), вы можете просто использовать вместо целого цикла while:

xargs -I{} bash -c 'mkdir -p "${2}/${1%.tar*}"' - '{}' "${QNAP}" < "${LOG_DIR}/${NOVA_TAR_LIST}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...