仅依赖于文件名上找到的模式来替换文件名和文件名的内容

仅依赖于文件名上找到的模式来替换文件名和文件名的内容

我想知道是否可以替换filename.ext其内容中关于基于以下内容的模式的匹配模式:文件名本身使用sed(也grep可能?)。

让我向您展示一些您可以重新创建的文件作为示例:

cat > '[2022] Diary 2022 (essay, Travels).txt' <<\EOF
TITLE/- Diary 2022 (essay, Travels) -\TITLE

@

sometext...
EOF
cat > '[2022] Diary 2022 (list, Recipes).txt' <<\EOF
TITLE/- Diary 2022 (list, Recipes) -\TITLE

@

sometext...
EOF
cat > '[2022] Diary 2022 (watchlist, Movies-).txt' <<\EOF
TITLE/- Diary 2022 (watchlist, Movies-) -\TITLE

@

sometext...
EOF
cat > '[2022] Diary 2022 (list, Movies+).txt' <<\EOF
TITLE/- Diary 2022 (list, Movies+) -\TITLE

@

sometext...
EOF

我想要使​​用的匹配模式是(从右到左的人类阅读)之间的一切结束右括号第一个遇到的空间

我想说这个模式是基于位置, 而不是单词或者数字或者还要别的吗

Foo Bar foobar(foob,匹配).ext

我认为这应该是正确的正则表达式>\(.+\s(\w.+)\)

我希望事情变成这样:

[2022] Diary 2022 (essay, Travels).txt> 变为 >travels.txt 并且其内容变为 >

TITLE/- travels -\TITLE

@

sometext...

[2022] Diary 2022 (watchlist, Movies-).txt> 变为 >movies-.txt 并且其内容变为 >

TITLE/- movies- -\TITLE

@

sometext...

[2022] Diary 2022 (list, Movies+).txt> 变为 >movies+.txt 并且其内容变为 >

TITLE/- movies+ -\TITLE

@

sometext...

等等...

答案1

sed无法进行此类文件重命名,因此您还需要其他东西,例如使用mv.

bash如果您有with的版本mapfile,则重命名和修改都很简单:

模组文件

#!/bin/bash

set -o noclobber

for filename; do
    if [[ $filename =~ ^'['[0-9]+']'[[:space:]]+(.*[[:space:]]([^[:space:]]+)')')'.txt'$ ]]; then

        old='TITLE/- '${BASH_REMATCH[1]}' -\TITLE'
        new='TITLE/- '${BASH_REMATCH[2]}' -\TITLE'
        out=${BASH_REMATCH[2]}.txt

        mapfile -d '' data <"$filename"
        printf '%s' "${data//"$old"/"$new"}" >"$out"
        # rm "$filename"
    fi
done
$ chmod +x modfile
$ ./modfile *.txt

答案2

zsh

rename_and_edit() {
  {
    printf 'TITLE/- %s -\\TITLE\n' $2:r &&
     tail -n+2
  } < $1 > $2 &&
    rm -f -- $1
}
autoload -Uz zmv
zmv -P rename_and_edit '* (*)\)(.txt)' '$1:l$2'

无论第一行包含什么内容,都会用新标题替换文件的第一行。要将所有出现的旧标题替换为新标题,无论它们出现在哪里:

zmodload zsh/mapfile
rename_and_edit() {
  local oldtitle="TITLE/- $1:r -\\TITLE" \
        newtitle="TITLE/- $2:r -\\TITLE"
  print -rn -- ${mapfile[$1]//$oldtitle/$newtitle} > $2 &&
    rm -f -- $1
}
autoload -Uz zmv
zmv -P rename_and_edit '* (*)\)(.txt)' '$1:l$2'

或者:

zmodload zsh/mapfile
rename_and_edit() {
  3=( 'TITLE/- '$^@:r' -\TITLE' )
  print -rn -- ${mapfile[$1]//$3/$4} > $2 &&
    rm -f -- $1
}
autoload -Uz zmv
zmv -P rename_and_edit '* (*)\)(.txt)' '$1:l$2'

相关内容