问题
I looked at this question: BASH Palindrome Checker. This is what the question answer shows from that thread:
grep -E '^[a-z]{3,45}$' /usr/share/dict/words | while read -r word;
do [ $word == `echo $word | rev` ] && echo $word;
done;
I understand that this is reading from "words" but have trouble trying to modify it to read from a text file instead of /usr/share/dict/words
. I want to have it to read any text file I request, so I can put:
source palindrome *filename*
and this will print out the palindromes found in the file in the console. Also later to have it so I can output to a output file:
source palindrome *filename* >> output.txt
I have tried to do this but it doesn't work and I am really not sure what I have to change to get it to read my file:
#!usr/bin/bash
function search
{
filename=$1
grep -E '^[a-z]{3,45}$' "$filename" | while read -r word;
do [ $word == `echo $word | rev` ] && echo $word;
done;
}
search $1
If any solutions are given could they be in a similar format? I haven't learned too many other techniques yet. If more complicated solutions are given could you explain the code given a little please.
The input file is from an eBook, it is extremely long so a small snippet is: (I do realise this doesn't show off palindromes in the snippet but it is just to show what kind of text file it is)
O and that lotion mustn't forget.
Fever near her mouth. Your head it simply. Hair braided over: shell with
seaweed. Why do they hide their ears with seaweed hair?
When running source palindrome filename there is no error message. I press enter and the terminal lets me type anything I want in again. It doesn't look as if it is running through the script
回答1:
#!/bin/bash
function search
{
grep -oiE '[a-z]{3,}' "$@" | tr '[:upper:]' '[:lower:]' | while read -r word; do
[[ $word == $(rev <<< "$word") ]] && echo "$word"
done
}
search "$@"
The dictionary this original code was written for had a single lowercase word on each line. To parse a text file with multiple mixed case words per line you need a few modifications:
- Remove the
^
and$
anchors from the regex to find words anywhere on a line. - Use
grep -o
to print out the matching words. - Use
grep -i
to match both upper and lowercase. - Use
tr
to switch uppercase letters to lowercase.
Other fixes:
- Changed the shebang line to
#!/bin/bash
. It ought to be an absolute path, and the two preferred forms are either#!/bin/bash
or#!/usr/bin/env bash
. - Changed
£word
to$word
. - Use
"$@"
sosearch()
can accept multiple file names.
Improvements:
- There's no particular reason to limit words to 45 characters.
{3,}
removes the upper limit. - Double brackets
[[ ]]
are better than single brackets[ ]
. $(cmd)
is better than`cmd`
.rev <<< "$word"
is better thanecho "$word" | rev
.
回答2:
Your shebang line is wrong. Change:
#!usr/bin/bash
to
#!/usr/bin/bash
or
#!/bin/bash
回答3:
How about this (no scripting):
comm -12 <(nl foo) <(rev foo | nl) | cut -f2
来源:https://stackoverflow.com/questions/47014928/printing-all-palindromes-from-text-file