使用包含“/”字符的 txt 文件名称创建目录

使用包含“/”字符的 txt 文件名称创建目录

我有一个 .txt 文件,其中包含如下文本

A1/B1/C1
A2/B2/C2 
A3/B3/C3

我想要一个脚本,读取 .txt 文件的每一行,然后根据第一个单词创建一个目录(A1、A2、A3)

我已经创建了这样的脚本:

file="test.txt"
while IFS='' read -r line
do
    name="line"
    mkdir -p $line
done <"$file"

当我运行它时,它会创建目录 A1,然后还会创建子目录 B1 和 C1。另一行(A2* 和 A3*)也会发生同样的情况

我应该怎么做才能仅创建 A1、A2、A3 目录?

我不想将名称改为 A1/B1/C1 之类的带有“/”字符的名称。我只想将“/”字符之前的单词作为目录名称。只需“A1”“A2”“A3”即可。

答案1

您可以只保留每行中以斜线分隔的cut字段并将列表提供给:1dmkdir

mkdir $(<dirlist.txt cut -d/ -f1)

示例运行

$ cat dirlist.txt 
A1/A2/A3
B1/B2/B3
C1/C2/C3
$ ls
dirlist.txt
$ mkdir $(<dirlist.txt cut -d/ -f1)
$ ls
A1  B1  C1  dirlist.txt

你可能会遇到最大参数如果你的列表包含巨大的目录名称的数量,在本例中使用 GNUparallel 平行安装或者xargs如下:

parallel mkdir :::: <(<dirlist.txt cut -d/ -f1)
xargs -a<(<dirlist.txt cut -d/ -f1) mkdir

虽然parallel已经涵盖了这一点,但xargs如果目录名称包含空格,该方法将不起作用——您可以将其用作\0行分隔符,或者简单地指示xargs仅在换行符上拆分输入(如建议的那样马丁·邦纳) 反而:

xargs -0a<(<dirlist.txt tr \\{n,0} | cut -d/ -f1 -z) mkdir # \\{n,0} equals \\n \\0
xargs -d\\n -a<(<dirlist.txt cut -d/ -f1) mkdir

如果任何字段包含换行符,则需要识别“真正的”行尾,并仅用 替换那些换行符,例如\0。那将是一个案例awk,但我觉得在这里太牵强了。

答案2

您需要设置您的IFS='/'for read,然后将每个第一个字段分配到单独的变量中first,将其余字段分配到变量中rest,然后只对第一个字段的值进行操作(或者您可以read -ar array对单个数组并使用"${array[0]}"第一个字段的值。):

while IFS='/' read -r first rest;
do
    echo mkdir -- "$first" 
done < test.txt

###或者对于那些喜欢它的人来说,用单行表示:

<test.txt xargs -d'\n' -n1 sh -c 'echo mkdir -- "$'{1%%/*}'"' _

###或者一次性创建所有目录:

<test.txt xargs -d'\n' bash -c 'echo mkdir -- "$'{@%%/*}'"' _

ANSI-C 引用$'...'用于处理包含特殊字符的目录名。

请注意,_末尾的(可以是任何字符或字符串)将是 argv[0],bash -c '...'并且$@将包含从 1 开始的其余参数;如果没有,在第二个命令中,第一个参数mkdir将会丢失。

${1%%/*}使用shell(POSIX sh/bash/Korn/zsh)参数替换扩展,删除最长的斜杠匹配,后跟任何内容,直到传递给它的参数的末尾,这是一行参数

附言:

  • 删除echo前面的mkdir以创建这些目录。
  • 如果您的列表以 NUL 字符而不是 ewline 分隔,则替换-d'\n'为(假设您的目录名中嵌入了换行符)。-0\n

答案3

内容test.txt

A 12"x4" dir/B b/C c
A1/B1/C1
A2/B2/C2
A3/B3/C3

创建A[123]文件夹的脚本:

file="test.txt"
while read -r line ; do
   mkdir "${line%%/*}"
done < "$file"

输出ls

A 12"x4" dir
A1
A2
A3

答案4

使用 Perl:

perl -ne 'mkdir for /^(\w+)/' list.txt

或者

perl -ne 'mkdir for /^([^\/]+)/' list.txt

如果我们想接受目录名上的空格

相关内容