查找命令,枚举输出并允许选择?


10

当我使用时find,它经常会发现多个结果,例如

find -name pom.xml
./projectA/pom.xml
./projectB/pom.xml
./projectC/pom.xml

我通常只想选择一个特定的结果(例如edit ./projectB/pom.xml)。有没有办法枚举find输出并选择要传递到另一个应用程序的文件?喜欢:

find <print line nums?> -name pom.xml
1 ./projectA/pom.xml
2 ./projectB/pom.xml
3 ./projectC/pom.xml

!! | <get 2nd entry> | xargs myEditor

[编辑]通过提到的一些解决方案,我遇到了一些重大错误。因此,我想说明重现步骤:

git clone http://git.eclipse.org/gitroot/platform/eclipse.platform.swt.git
cd eclipse.platform.swt.git
<now try looking for 'pom.xml' and 'feature.xml' files>

[编辑]解决方案1 到目前为止,如果我将'nl'(足够的输出),头和尾结合起来使用函数$(!!),头和尾似乎可以正常工作。

即:

find -name pom.xml | nl   #look for files, enumirate output.

#I then define a function called "nls"
nls () {
  head -n $1 | tail -n 1
}

# I then type: (suppose I want to select item #2)
<my command> $(!!s 2)

# I press enter, it expands like: (suppose my command is vim)
vim $(find -name pom.xml |nls 2)

# bang, file #2 opens in vim and Bob's your uncle.

[编辑]解决方案2 使用“选择”似乎也很好。例如:

  findexec () {
          # Usage: findexec <cmd> <name/pattern>
          # ex: findexec vim pom.xml
          IFS=$'\n'; 
          select file in $(find -type f -name "$2"); do
                  #$EDITOR "$file"
                  "$1" "$file"
                  break
          done;  
          unset IFS
  }

Your find command | head -TheNumberYouWant满足您的要求?(与您的专线:!! | head -2 | xargs myEditor
ADDB

1
fzf,它将这种动作绑定到^ T(默认情况下)
Tavian Barnes

Answers:


16

使用bash的内置功能select

IFS=$'\n'; select file in $(find -type f -name pom.xml); do
  $EDITOR "$file"
  break
done; unset IFS

对于在注释中添加的“奖励”问题:

declare -a manifest
IFS=$'\n'; select file in $(find -type f -name pom.xml) __QUIT__; do
  if [[ "$file" == "__QUIT__" ]]; then
     break;
  else
     manifest+=("$file")
  fi
done; unset IFS
for file in ${manifest[@]}; do
    $EDITOR "$file"
done
# This for loop can, if $EDITOR == vim, be replaced with 
# $EDITOR -p "${manifest[@]}"

4
+1提供我怀疑是很少使用的命令动词
roaima

我正在努力。 select似乎与修改并不相称IFS
DopeGhoti

3
啊。( IFS=$'\n'; select file in $(find -maxdepth 2 -name '*.txt'); do echo "$file"; done; )
roaima

我应该想到C风格的字符串。做得好!
DopeGhoti

1
我将不胜感激,@ roaima: unix.stackexchange.com/questions/378282/…–
DopeGhoti

3

只要文件名不包含换行符或其他非打印字符,两个小功能将帮助您解决此问题。(它确实处理包含空格的文件名。)

findnum() { find "$@" | sed 's!^\./!!' | nl; }
wantnum() { sed -nr "$1"'{s/^\s+'"$1"'\t//p;q}'; }

findnum -name pom.xml
     1  projectA/pom.xml
     2  projectB/pom.xml
     3  projectC/pom.xml

!! | wantnum 2
projectB/pom.xml

方便地,显式文件pom.xml名将永远不包含空格(:
DopeGhoti

上面似乎有一些错误。find -name pom.xml将给我很多输出,但是findnum只给我一行。例如./features/org.eclipse.swt.tools.feature/pom.xml ./examples/org.eclipse.swt.examples.ole.win32/pom.xml ./examples/org.eclipse.swt.examples/pom .xml ./examples/org.eclipse.swt.examples.views/pom.xml ./examples/org.eclipse.swt.examples.launcher/pom.xml ./examples/org.eclipse.swt.examples.browser。 demos / pom.xml ./local-build/local-build-parent/pom.xml
Leo Ufimtsev

在同一数据集上的@Leo您是如何使用的findnum
roaima

希望此屏幕截图有助于解释该问题:i.imgur.com/hfneWJn.png 您可能会观察到feature.xml产生3个结果。与findnum功能,我得到一个错误。使用fundnum pom.xml时,它仅显示一个结果,而find -name pom.xml时将显示3个结果。我更新了问题以解释如何获取数据集。(这是一个简单的git repo)
Leo Ufimtsev

1
@DopeGhoti,尽管它可能位于以空格d命名的目录中
通配符

3

您可以得到总输出的开头,并以-1结尾。这可以通过其他命令或编辑器输出输出。

(给我100行,并在最后一条管道上打印100),找到。| 头-100 | 尾-1

xxx@prod01 (/home/xxx/.ssh) $ find .
.
./authorized_keys
./id_rsa
./id_rsa.pub
./id_rsa_b_x.pub
./id_rsa_a_y.pub
./known_hosts

xxx@prod01 (/home/xxx/.ssh) $ find . | head -3
.
./authorized_key
./id_rsa

xxx@prod01 (/home/xxx/.ssh) $ find . | head -3 | tail -1
./id_rsa    



eg: vim "$(find . | head -100 | tail -1)"

将为您找到第100行。


1
好吧,简单的解决方案似乎是最好的。您的答案与'nl'和'$(!!)'结合起来实际上似乎效果很好。我在问题中张贴了详细信息。感谢您的回应。
Leo Ufimtsev

1

如果您的目标是搜索后编辑文件,请尝试sag / sack

例:

$ sag skb_copy                                                                
sack__option is: -ag

============> running ag! <============

===> Current Profile: no_profile
===> Using flags: 
===> Searching under: /home/fklassen/git/pvc-appliance/kernel/drivers/ixgbevf
===> Searching parameters: skb_copy


/home/fklassen/git/pvc-appliance/kernel/drivers/ixgbevf/kcompat.c
[1] 195:        skb_copy_bits(skb, offset, buffer, len) < 0)

/home/fklassen/git/pvc-appliance/kernel/drivers/ixgbevf/kcompat.h
[2] 1774:   if (skb_copy_bits(skb, offset, buffer, len) < 0)
[3] 2321:#define skb_copy_to_linear_data(skb, from, len) \
[4] 2323:#define skb_copy_to_linear_data_offset(skb, offset, from, len) \

...然后编辑最后的搜索结果....

F 4

优点是您可以稍后返回以编辑第一个搜索结果

F 1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.