我有一个命令,可以计算以2010开头的所有文件名
find folder_name/ -path '*/*/*/*/2010*'
这很好,我得到了有效的结果。但是,举例来说,我具有以下文件结构:
*/atl/apple/banana/20101004
*/atl/apple/oranges/20101004
这些都属于同一类别,因为它们都属于atl。因此,不是计数为2,而是应该为1。有没有办法使我仅获得每个城市名称(atl)的唯一值?
注意:末尾的日期是文件名。没有文件扩展名。
编辑 假设我有这个命令
find example/ -path '*/*/*/*/2010*'
我得到这些作为结果:
example/atl/apples/bananas/20100510 //1 instance of this date in atl
example/atl/apples/oranges/20100510 //This date is a duplicate and should not be counted
example/nyc/apples/bananas/20100510 //1 instance of this date in nyc
example/nyc/apples/bananas/20100511 //1 instance of this date in nyc
example/bkg/apples/bananas/20100510 //1 instance of this date in bkg
在此示例中,计数应为4。atl中的20100510显示多次,因此应仅计数一次。
答案 0 :(得分:0)
使用sort
显示唯一的城市/日期对,加上wc
对其进行计数,并使用bash
处理替代使其看起来更好:>
find folder_name/ -path '*/*/*/*/2010*' |
sort -t '/' -k 2,2 -k 5,5 -u | tee >(echo "Count: $(wc -l)")
输出(根据“结果” 示例数据):
example/atl/apples/bananas/20100510
example/bkg/apples/bananas/20100510
example/nyc/apples/bananas/20100510
example/nyc/apples/bananas/20100511
Count: 4
或者仅打印城市/日期对,请在cut
之前添加tee
:
find folder_name/ -path '*/*/*/*/2010*' |
sort -t '/' -k 2,2 -k 5,5 -u | cut -d '/' -f 2,5 | tee >(echo "Count: $(wc -l)")
输出:
atl/20100510
bkg/20100510
nyc/20100510
nyc/20100511
Count: 4
工作原理:
find
一些文件,深五个级别。sort
按第二和第五字段排序,仅打印唯一的城市/日期行。请注意,需要两个 -k
开关;仅使用-k 2,5
不会以相同的方式工作。wc
计算行数。答案 1 :(得分:0)
如果使用awk
仅选择城市名称和文件名等字段,则可以通过管道传输到sort -u
,然后通过wc
进行计数。这将对来自同一城市的所有结果产生一次计数。像这样:
find folder_name/ -path '*/*/*/*/2010*' |
awk -F/ '{ print $2, $5 }' |
sort |
uniq -c
答案 2 :(得分:0)
使用find
本身(而不是依赖外部工具)来进行除mkdir -p example/{atl,nyc,bkg}/apples/{bananas,oranges}
touch \
example/atl/apples/bananas/20100510 \
example/atl/apples/oranges/20100510 \
example/nyc/apples/bananas/20100510 \
example/nyc/apples/bananas/20100511 \
example/bkg/apples/bananas/20100510
本身之外的所有操作可能看起来如下所示。
给出问题中描述的设置:
#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*) echo "ERROR: Bash 4.0 needed" >&2; exit 1;; esac
declare -A seen=( )
while IFS= read -r -d '' name; do
name=${name#example/} # ignore the leading example/
first_piece=${name%%/*}
last_piece=${name##*/}
seen[${first_piece}/${last_piece}]=1
done < <(find example -type f -print0)
echo "Number of distinct first/last pairs: ${#seen[@]}"
echo "Those individual pairs are:"
printf ' - %s\n' "${!seen[@]}"
...实现:
Number of distinct first/last pairs: 4
Those individual pairs are:
- atl/20100510
- bkg/20100510
- nyc/20100510
- nyc/20100511
...正确发出作为输出:
git commit -am "message" --author="Linus Torvalds <torvalds@linux-foundation.org>"
答案 3 :(得分:0)
通过@charles的启发,我创建了以下结构:
mkdir -p example/{atl,nyc,bkg}/apples/{bananas,oranges}
touch \
example/atl/apples/bananas/20100510 \
example/atl/apples/oranges/20100510 \
example/nyc/apples/bananas/20100510 \
example/nyc/apples/bananas/20100511 \
example/bkg/apples/bananas/20100510 \
example/bkg/coconuts/bananas/20100510
然后,假设您认为文件是重复的,因为它位于同一 level-2 子目录(苹果或椰子)中,我建议使用以下命令:
for i in $(find example -maxdepth 2 -mindepth 2 -type d); do find $i -path '*/*/*/*/2010*'|awk -F\/ '{print $NF}'|sort -u;done|wc -l
结果是:
5
如果由于文件位于相同的 level-1 子目录(atl,nyc或bkg)中,因此要考虑它是重复文件,请使用以下命令:
for i in $(find example -maxdepth 1 -mindepth 1 -type d); do find $i -path '*/*/*/*/2010*'|awk -F\/ '{print $NF}'|sort -u;done|wc -l
结果是:
4