如何创建以每个月命名的目录?

Jam*_*its 8 xargs shell-script bash-expansion

我想为每个月创建一个目录名称。我知道,在玩了一些 shell 之后,:

date -d 1/01 +%b # Gives Jan
date -d 2/01 +%b # Gives Feb
.
date -d 12/01 +%b # Gives Dec
Run Code Online (Sandbox Code Playgroud)

所以我使用了大括号扩展,echo {1..12}/01并尝试了xargs它:

echo {1..12}/01 | xargs -n 1 -I {} date -d {} +%b
Run Code Online (Sandbox Code Playgroud)

但它失败了:/(之后我想申请mkdir)。我怎样才能做到这一点?

Sté*_*las 17

使用-I,xargs每行获取一个参数,而不是默认每个(空白或换行符分隔,可能引用)单词没有-I(并暗示-n)一个参数。因此,在您的示例中,date仅调用一次并{}扩展到整个输出echo(在一行上),减去尾随的换行符。

在这里你可以做(​​请注意,这-d是一个 GNU 扩展):

printf '%s\n' {1..12}/01 | xargs -I {} date -d {} +%b | xargs mkdir --
Run Code Online (Sandbox Code Playgroud)

(请注意,在月份名称缩写包含空格或引号字符的语言环境中,它无法正常工作;使用 GNU xargs,您可以使用 来解决这个问题xargs -d '\n' mkdir --

现在,要在您的语言环境中获取月份缩写列表,直接查询语言环境会更有意义:

(IFS=';'; set -o noglob; mkdir -- $(locale abmon))
Run Code Online (Sandbox Code Playgroud)

(另请参阅locale -k LC_TIME以查看LC_TIME类别中的所有语言环境数据)。

或本机在zsh

zmodload zsh/langinfo
mkdir -- ${(v)langinfo[(I)ABMON_*]}
Run Code Online (Sandbox Code Playgroud)

至少在 GNU 系统上,在某些语言环境中,月份缩写会用空格填充到固定宽度:

$ LC_ALL=et_EE.UTF-8 locale title abmon
Estonian locale for Estonia
jaan ;veebr;märts;apr  ;mai  ;juuni;juuli;aug  ;sept ;okt  ;nov  ;dets
$ LC_ALL=zh_TW.UTF-8 locale title abmon
Chinese locale for Taiwan R.O.C.
 1?; 2?; 3?; 4?; 5?; 6?; 7?; 8?; 9?;10?;11?;12?
Run Code Online (Sandbox Code Playgroud)

您可能想要删除该填充。

前导空格将被删除xargs -I,但不会被尾随空格删除。与zsh

zmodload zsh/langinfo
set -o extendedglob
mkdir -- ${${${(v)langinfo[(I)ABMON*]}##[[:space:]]#}%%[[:space:]]#}
Run Code Online (Sandbox Code Playgroud)


mau*_*wns 9

试试循环?

$ for m in {1..12}; do
> date -d "$m"/01 +%b
> done
jan
feb
mar
apr
maj
jun
jul
aug
sep
okt
nov
dec
Run Code Online (Sandbox Code Playgroud)

如果你想为每个月制作一个目录,我会做这样的事情:

for m in {1..12}; do newdir=$(date -d "$m"/01 +%b); mkdir "$newdir"; done
Run Code Online (Sandbox Code Playgroud)

  • @RadovanGarabík,从技术上讲,`{1..12}` 是一种 zshism,后来被 ksh93、bash 和其他几个 shell 复制。 (2认同)

pLu*_*umo 5

您的命令不起作用,因为使用-I更改了 xargs 的分隔符:

-I replace-str
用从标准输入读取的名称替换初始参数中出现的 replace-str。此外,未加引号的空格不会终止输入项;相反,分隔符是换行符。

您可以添加-d " "到 xargs 以使其工作。但-I{}在你的情况下你甚至不需要:

尝试这个,

echo {1..12}/01 | xargs -n1 date +%b -d | xargs mkdir
Run Code Online (Sandbox Code Playgroud)


Rud*_*diC 5

在带有括号扩展和日期接受 DATAFILE 输入的 shell 中,尝试

echo {01..12}/01$'\n' | date -f- +"mkdir %b"
Run Code Online (Sandbox Code Playgroud)

如果对结果感到满意,则将其输送到外壳中。