【问题标题】:List directories and their files grouping them on one line for tokenization列出目录及其文件,将它们分组在一行中以进行标记化
【发布时间】:2018-05-23 16:52:05
【问题描述】:

我想在 bash 脚本中将目录名称与其文件分组。 例如,如果我输入 ls /home/maindir/*

我收到home/maindir/dir1: file1 file2\n file3 home/maindir/dir2: file1 file2

包含文件的目录没有用指定的分隔符分隔,因为在同一目录中的文件 1 和文件 2 之间存在换行符,所以我想用分隔符标记目录名称及其文件列表在一条线上。 带有换行符的示例输出:

home/maindir/dir1: file1 file2 file3\n
home/maindir/dir2: file1 file2\n
home/maindir/dir3: file1 file2 file4\n

【问题讨论】:

  • 这实际上是最终目标,还是只是您想要解析以做其他事情的东西?因为你描述的是可能的,但是做起来有点乱;如果您实际上只是想将其解析为其他形式,则可能有更好的方法。
  • Stack Overflow 不是代码编写服务。请出示您的代码。由于 Stack Overflow 向您隐藏了关闭原因:寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及在问题本身。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example

标签: linux bash shell terminal


【解决方案1】:

我最初使用了一个未引用的插值技巧。 例如,如果您在文件中有字符串,每行一个,并且您希望它们水平化,则不必使用 paste -

名为 foo 的文件:

a
b
c

那么你可以说:

echo $(<foo)

你得到

a b c

但这可能会导致文件名出现问题,特别是如果它们嵌入了特殊字符或空格。

感谢 Gordon Davisson 的简单升级!

for d in /home/maindir/*    # includes full path each time
do [[ -d "$d" ]] || continue  # ignore nondirectories
   cd "$d"                    # go there to make filenames path-bare
   echo "$d:" * 
done

请注意,这仍然包括子目录。你需要跳过那些吗? 如果你想更加小心 -

for d in /charter/apps/*
do [[ -d "$d" ]] || continue
   cd "$d"
   dir="$d: "
   hit=0
   for f in *
   do if [[ -f "$f" ]]
      then hit=1
           dir="$dir $f "
      fi
   done
   (( $hit )) && printf "$dir\n"
done

这也应该适用于带有嵌入空格 &c 的文件。

【讨论】:

  • 如果目录名带有空格(或制表符或...),文件名带有通配符等,这将有问题。最好引用所有变量引用,设置nullglob,并且使用echo "$d:" * 获取文件列表。
  • 如果变量可以是路径,您还应该引用它。这意味着您需要在 if 语句中以及在运行 cd 时引用 $d
  • 我知道没有子目录,也没有带通配符或空格的文件名。
  • 除非您有充分的具体理由避免它,否则仍然是一个好政策。
  • @RobertSeaman [[ ]] 不需要引用,因此即使$d 中有空格或全局字符,[[ -d $d ]] 也不会中断。不过,引用并没有什么坏处。
猜你喜欢
  • 2013-10-29
  • 2012-05-06
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多