знайти команду, перерахувати вихід і дозволити вибір?


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 Використання "select" також, здається, працює добре. колишній:

  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

Відповіді:


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

Я мав би подумати про струни у стилі С. Молодці!
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 на тому ж наборі даних, як ти користувався findnum?
roaima

Сподіваємось, цей знімок екрана допоможе пояснити проблему: i.imgur.com/hfneWJn.png Ви можете помітити, що функція.xml дає 3 результати. з функцією findnum я отримую помилку. з fundnum pom.xml він друкує лише один результат, де як find -name pom.xml друкує 3 результати. Я оновив своє запитання, щоб пояснити, як отримати набір даних. (це проста git repo)
Лев Уфімцев

1
@DopeGhoti, хоча це може бути в каталозі з ім'ям пробілів d:
Wildcard

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' та '$ (!!)', здається, працює насправді добре. Я розмістив деталі у своєму запитанні. Дякуємо за відповідь
Лев Уфімцев

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.