Мое решение (, используемое ежедневно ), заключается в использовании alias
для xdg-open
.
Просто наденьте это на~/.bashrc
:
alias open='xdg-open '
Затем закройте и перезапустите оболочку или source ~/.bashrc
.
Теперь с помощью этой команды можно открыть любой файл... от.png до.jpg, от.docx до.pdf и.txt.
Я разбил все на функции, чтобы упростить понимание:
#!/bin/bash
# For the next two functions, we will use "-print0", which will print out \0 instead of \n.
# This will help prevent whitespace problems when piping the filenames into xargs.
find_extension()
{
find "$1" -type f -name "*.$2" -print0 2>/dev/null
}
find_no_extension()
{
find "$1" -type f -regex '^.*/[^.]+$' -print0 2>/dev/null
}
concat_files()
{
xargs -0 cat
}
delete_empty_lines()
{
sed -E '/^[[:space:]]*$/d'
}
line_count_of_files()
{
concat_files | delete_empty_lines | wc -l
}
print_usage()
{
echo "Usage: $0 [EXTENSION]... [SEARCH_DIRECTORY]";
}
NUMBER_OF_EXTENSIONS=$(($# - 1))
SEARCH_DIR="${*: -1}"
if [ $# -lt 2 ];
then
echo "Not enough parameters.";
print_usage;
exit 1;
fi
if ! [ -d "$SEARCH_DIR" ];
then
echo "$SEARCH_DIR does not exist, or is not a directory."
print_usage;
exit 1;
fi
for EXTENSION in "${@:1:$NUMBER_OF_EXTENSIONS}";
do
printf ".$EXTENSION: %s\n" $(find_extension "$SEARCH_DIR" "$EXTENSION" | line_count_of_files)
done
printf "No extension: %s\n" $(find_no_extension "$SEARCH_DIR" | line_count_of_files)
Это скорее общий скрипт, который позволяет указать произвольные расширения файлов для поиска. Однако он всегда будет искать файлы без расширения.
Вы должны сохранить это в файл, дать ему разрешение на выполнение и поместить в свой PATH. Допустим, вы назвали его count _lines.sh. Вы можете назвать это так:count_lines.sh py md yaml ~/Code
. Это будет искать в каталоге ~/Code
файлы, оканчивающиеся на .py
, .md
и .yaml
, а также файлы без расширения вообще. Вы можете выбрать любое количество расширений для поиска, просто убедитесь, что у вас есть хотя бы одно.
Попробуйте это
find./ -not -path "./.git/*" -type f -exec wc -l {} + |
awk '{print tolower($0)}' |
sed -e '$ d' |
sed -e "s#/.*/##g" |
sed -e "s/\./ \./g" |
awk '
{ if ( NF <= 2 ) { count["none"] += $1 } else { count[$NF] += $1 } }
{ next }
END { for (group in count) printf("%d%s%s\n", count[group], OFS, group) }
' |
sort -n
В разобранном виде:
find./
найти объекты в этом каталоге, рекурсивно -not -path "./.git/*"
кроме.git
-type f
файлы, а не каталоги -exec wc -l {} +
для каждого файла запустите утилиту подсчета слов(wc
). Это включает пустые строки, поэтому не отвечает всем требованиям вопроса. awk '{print tolower($0)}'
сделать строчными sed -e '$ d'
удалить последнюю строку, которая является суммой строк по всем файлам sed -e "s#/.*/##g"
удалить путь к файлу, например. a/something.egg/blah
должно считаться отсутствием расширения, а не .egg/blah
расширением sed -e "s/\./ \./g" search/replace
. with
. `, поэтому расширение файла — это собственное слово awk '{ if ( NF <= 2 ) { count["none"] += $1 } else { count[$NF] += $1 } } { next } END { for (group in count) printf("%d%s%s\n", count[group], OFS, group) }'
это большой. awk
мощный, но не очень четкий count
это словарь if (NF <= 2)
если «слов» меньше 3, т.е.нет расширения count["none"] += $1
увеличить элемент в словаре, ключ является строковым литералом none
, увеличить его, добавив количество строк в этом файле, которое является первым словом, которое равно $1 count[$NF] += $1
увеличить элемент в словаре, ключ — это $NF
, которое является последним словом в строке, которое является расширением, на $1
, которое является первым словом в строке, что является количеством строк в этом файл { next }
повторить для всех строк, то, что после next
сделать только один раз for (group in count)
цикл for, встроенный printf(...)
отформатировать выходную строку как 123.abc
(, если в файлах 123 строки, заканчивающиеся на.abc
)sort -n
сортировать результаты в порядке возрастания, -n
означает сортировать как число, а не строку Если я вас правильно понял, и мои тесты хороши, я предлагаю это (при условии, что вы хотите пропустить скрытые каталоги и файлы, скажите мне, если это не так):
shopt -s globstar
declare -A arr
for f in test/**; do
# if a directory, skip
[[ -d "$f" ]] && continue
lines=0
# strip the extension
ext="${f##*.}"
# convert it to lowercase
ext="${ext,,}"
# if no dot in the name, extension is "empty"
[[ ! $(basename "$f") =~ \. ]] && ext="empty"
# count the lines
lines=$(wc -l "$f"| cut -d' ' -f1)
# if lines equals to 0, skip
[[ $lines -eq 0 ]] && continue
# append the number of line to the array
lines=$(( "${arr[$ext]}"+$lines ))
arr[$ext]=$lines
done
# loop over the array
for n in ${!arr[@]}; do
echo "files $n: total lines ${arr[$n]}"
done
Вывод (из моих файлов примеров):
files yaml: total lines 3
files md: total lines 3
files empty: total lines 4
files csv: total lines 6
files py: total lines 5