Как я могу манипулировать именами файлов, используя bash и sed? - PullRequest
5 голосов
/ 30 августа 2011

Я пытаюсь перебрать все файлы в каталоге.

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

for file in `find /home/devel/stuff/static/ -iname "*.pdf"`;
do
  echo $file;
  sed -e 's/static/changethis/' $file > newfile +".xml";
  echo $newfile;
done

Я хочу получить следующие результаты:

$ file => /home/devel/stuff/static/2002/hello.txt

$ newfile => /home/devel/stuff/changethis/2002/hello.txt.xml

Как мне изменить мою sed строку?

Ответы [ 6 ]

5 голосов
/ 30 августа 2011

Если вам нужно переименовать несколько файлов, я бы предложил использовать команду rename:

# remove "-n" after you verify it is what you need
rename -n 's/hello/hi/g' $(find /home/devel/stuff/static/ -type f)

или, если у вас нет rename, попробуйте это:

find /home/devel/stuff/static/ -type f | while read FILE
do
    # modify line below to do what you need, then remove leading "echo" 
    echo mv $FILE $(echo $FILE | sed 's/hello/hi/g')
done
3 голосов
/ 30 августа 2011

Вы пытаетесь изменить имя файла? Тогда

for file in /home/devel/stuff/static/*/*.txt
do
    echo "Moving $file"
    mv "$file" "${file/static/changethis}.xml"
done

Пожалуйста, убедитесь, что /home/devel/stuff/static/*/*.txt это то, что вы хотите, прежде чем использовать скрипт.

1 голос
/ 30 августа 2011

Я бы не стал выполнять цикл for из-за возможности перегрузки командной строки.Командные строки имеют ограниченную длину, и если вы перегрузите их, они просто сбросят лишние, не предупреждая вас.Это может сработать, если ваша находка вернет 100 файлов.Он может работать, если он возвращает 1000 файлов, но может не работать, если ваш поиск возвращает 1000 файлов, и вы никогда не узнаете.

Лучший способ справиться с этим - передать поиск в оператор чтения в виде glenn jackman .

Команда sed работает только на STDIN и на файлах, но не на именах файлов, поэтому, если вы хотите изменить имя файла, вам придется сделать что-то подобное:

$newname="$(echo $oldname | sed 's/old/new/')"

, чтобы получить новое имя файла.Конструкция $() выполняет команду и помещает результаты команды в STDOUT.

Итак, ваш скрипт будет выглядеть примерно так:

find /home/devel/stuff/static/ -name "*.pdf" | while read $file
do
    echo $file;
    newfile="$(echo $file | sed -e 's/static/changethis/')"
    newfile="$newfile.xml"
    echo $newfile;
 done

Теперь, так как вы переименовываете файловый каталог, вам нужно убедиться, что каталог существует, прежде чем вы сделаетепереместить или скопировать:

find /home/devel/stuff/static/ -name "*.pdf" | while read $file
do
    echo $file;
    newfile="$(echo $file | sed -e 's/static/changethis/')"
    newfile="$newfile.xml"
    echo $newfile;

    #Check for directory and create it if it doesn't exist
    $dirname=$(dirname "$newfile")
    if [ ! -d "$dirname" ]
    then
        mkdir -p "$dirname"
    fi

    #Directory now exists, so you can do the move
    mv "$file" "$newfile"
 done

Обратите внимание на кавычки, если в имени файла есть пробел.

Кстати, вместо этого:

if [ ! -d "$dirname" ]
then
    mkdir -p "$dirname"
fi

Вы можете сделать это:

[ -d "$dirname"] || mkdir -p "$dirname"

|| означает выполнить следующую команду, только если тест не соответствует действительности.Таким образом, если [-d "$ dirname"] является ложным утверждением (каталог не существует), вы запускаете mkdir.

Это довольно распространенный ярлык, когда вы видите сценарии оболочки.

1 голос
/ 30 августа 2011

Сначала вы должны создать имя нового файла на основе имени исходного файла.Очевидное решение:

newfile=${file/static/changethis}.xml

Во-вторых, вы должны убедиться, что новый каталог существует, или создать его, если нет:

mkdir -p $(dirname $newfile)

Затем вы можете что-то сделать со своим файлом:

doSomething < $file > $newfile
0 голосов
/ 22 января 2016
OUTPUT="$(pwd)";
for file in `find . -iname "*.pdf"`;
do
  echo $file;
  cp $file $file.xml
  echo "file created in directory = {$OUTPUT}"
done

Это создаст новый файл с именем whatyourfilename.xml, для hello.pdf новый созданный файл будет hello.pdf.xml, в основном он создает новый файл с добавлением .xml в конце.

Помните, что приведенный выше скрипт находит файлы в каталоге /home/devel/stuff/static/, имена файлов которых соответствуют строке соответствия команды find (в данном случае * .pdf), и копирует ее в ваш текущий рабочий каталог.

Команда find в этом конкретном сценарии находит только файлы с именами файлов, заканчивающимися на .pdf. Если вы хотите запустить этот сценарий для файлов с именами файлов, заканчивающимися на .txt, то вам нужно изменить команду поиска на find /home/devel/stuff/static/ -iname "*.txt", * 1008.*

0 голосов
/ 30 августа 2011
find ... | while read file; do
  newfile=$(basename "$file").xml;
  do something to "$file" > "$somedir/$newfile"
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...