Я хочу вырезать определенную длину строки в начале моего файла и добавить ее к моему имени файла. Есть ли одна строка, которая может сделать это для целого каталога файлов?

Например, у меня есть файл 1.txt со следующим содержимым:

123456abcdefg12345678...

Я хочу переименовать файл в 1_123456.txt и отредактировать содержимое:

abcdefg12345678....

Я создал bash-скрипт для решения этой проблемы, вот так:

for f in ./*; do
  a = $(head -c 8 $f)
  cut -c 9- > $f
  mv {,$a_}$f
done

Но это не делает то, что он должен делать - проблема, кажется, в линии mv. Я также был бы признателен, если бы одна строчка могла бы сделать свое дело.

0
tunawolf 15 Май 2019 в 11:17

2 ответа

Лучший ответ
$ echo 123456abcdefg12345678 > 1.txt
$ tail -c +7 1.txt > 1_$(head -c +6 1.txt).txt ; rm 1.txt . 
$ cat 1_123456.txt 
abcdefg12345678
1
William Pursell 18 Май 2019 в 18:21

Может быть, не один вкладыш (если вы не поместите его в сценарий оболочки), но вы можете попробовать это:

#!/bin/bash

# require two parameters:
# 1 the name of the input directory and
# 2 the name of the output directory
if [ $# -ne 2 ]
then
  echo usage
  exit 1
fi

INDIR=$1
OUTDIR=$2
CHAR_CNT=4                         # Number of chars to take from file content and insert into output file name

# Create the output directory just in case it does not exist.
mkdir -p $OUTDIR

# for each file.
for FILENAME in $INDIR/*
do
  if [ -f $FILENAME ]              # Make sure it is a regular file.
  then
    BASENAME=`basename $FILENAME`  # Extract just the file name.

    NAMEPART=${BASENAME%.*}        # From the file name, get just the name part.
    EXT=${BASENAME##*.}            # From the file name, get just the extension.
    PREFIX=`head -1 $FILENAME | cut -c 1-$CHAR_CNT`    # Get the first n characters from the input file.
    NEWFILE=$OUTDIR/${NAMEPART}_$PREFIX.$EXT   # Construct the output file name (and output path)

    # Degugging statements to show what is going on.
    #echo file: $FILENAME - NamePart: $NAMEPART, extension: $EXT, prefix = $PREFIX
    #echo new file name: $NEWFILE

    # Transfer the input file to the output, remove the first n characters from the file.
    # The output file will be named as per the format originalName_charsFromFile.extension
    sed "1s/^.\{$CHAR_CNT\}//" < $FILENAME > $NEWFILE
    echo "processed: $FILENAME -> $NEWFILE"
  else                             # Not a regular file.
    echo skipping $FILENAME
  fi
done

Я поместил вышеупомянутое в сценарий под названием renameSpecial.sh. Когда я запускаю его, я получаю результат, показанный ниже.

gmc@linux-ihon:~/projects/so/renFil>   #### Starting point - input files
gmc@linux-ihon:~/projects/so/renFil> tree .
.
└── sampleData
    ├── file1.txt
    ├── file2.txt
    ├── testdir
    │   └── ignoredFile.txt
    ├── t.txt
    └── x.y.z.txt

2 directories, 5 files
gmc@linux-ihon:~/projects/so/renFil> cat sampleData/x.y.z.txt 
1234567890abcdefg
gmc@linux-ihon:~/projects/so/renFil> cat sampleData/t.txt 
12aaaa
34bbb
56cccc
gmc@linux-ihon:~/projects/so/renFil> cat sampleData/file2.txt 
abcdefg
gmc@linux-ihon:~/projects/so/renFil> cat sampleData/file1.txt
aaaaaaa
gmc@linux-ihon:~/projects/so/renFil> 
gmc@linux-ihon:~/projects/so/renFil> 
gmc@linux-ihon:~/projects/so/renFil>  #### Run the command
gmc@linux-ihon:~/projects/so/renFil> renameSpecial.sh 
usage: /home/glennm/bin/renameSpecial.sh inDir outDir
where:
  inDir    the name of a directory containing the input files
  outDir   the name of a directory that will contain the output files
           if outDir does not exist, this script will create it.

gmc@linux-ihon:~/projects/so/renFil> 
gmc@linux-ihon:~/projects/so/renFil> renameSpecial.sh sampleData outData
processed: sampleData/file1.txt -> outData/file1_aaaa.txt
processed: sampleData/file2.txt -> outData/file2_abcd.txt
skipping sampleData/testdir
processed: sampleData/t.txt -> outData/t_12aa.txt
processed: sampleData/x.y.z.txt -> outData/x.y.z_1234.txt
gmc@linux-ihon:~/projects/so/renFil> 
gmc@linux-ihon:~/projects/so/renFil> #### Result new directory with *new* file names
gmc@linux-ihon:~/projects/so/renFil> 
gmc@linux-ihon:~/projects/so/renFil> tree .
.
├── outData
│   ├── file1_aaaa.txt
│   ├── file2_abcd.txt
│   ├── t_12aa.txt
│   └── x.y.z_1234.txt
└── sampleData
    ├── file1.txt
    ├── file2.txt
    ├── testdir
    │   └── ignoredFile.txt
    ├── t.txt
    └── x.y.z.txt

3 directories, 9 files
gmc@linux-ihon:~/projects/so/renFil> 
gmc@linux-ihon:~/projects/so/renFil> ### Finally, the chars used in the file names are removed from the beginning of the file.
gmc@linux-ihon:~/projects/so/renFil> 
gmc@linux-ihon:~/projects/so/renFil> cat outData/x.y.z_1234.txt 
567890abcdefg
gmc@linux-ihon:~/projects/so/renFil> cat outData/t_12aa.txt 
aa
34bbb
56cccc
gmc@linux-ihon:~/projects/so/renFil> 

Если вы хотите «переименовать» файлы, просто добавьте rm $FILENAME после шага sed в нижней части оператора if.

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

0
GMc 18 Май 2019 в 06:30