我试图收集鱼类文稿中的用户输入,特别是以下常见形式:
This command will delete some files. Proceed (y/N)?
经过一番搜索后,我仍然不确定如何干净利落。
这是在鱼类中这样做的特殊方式吗?
答案 0 :(得分:19)
我所知道的最好的方法是使用内置read
。如果您在多个地方使用它,您可以创建此辅助函数:
function read_confirm
while true
read -l -P 'Do you want to continue? [y/N] ' confirm
switch $confirm
case Y y
return 0
case '' N n
return 1
end
end
end
并在脚本/函数中使用它:
if read_confirm
echo 'Do stuff'
end
有关更多选项,请参阅文档: https://fishshell.com/docs/current/commands.html#read
答案 1 :(得分:4)
这与选择的答案相同,但只有一个功能,对我来说似乎更清晰:
class Program
{
static void Main(string[] args)
{
var input = "0 1 2 4 6 7";
var result = Solve(input);
}
private static int Solve(string input)
{
var digits = input.Split(' ').Select(i => int.Parse(i)).ToArray();
return GetSmallestDifference(digits) ?? -1;
}
public static int? GetSmallestDifference(IEnumerable<int> input)
{
var validInput = ValidateInput(input);
var candidates = GenerateCandidates(validInput);
int? best = null;
foreach (var candidate in candidates)
{
var current = Math.Abs(candidate.Item1 - candidate.Item2);
if (current < (best ?? int.MaxValue))
{
best = current;
}
}
return best;
}
private static IEnumerable<Tuple<int, int>> GenerateCandidates(int[] validInput)
{
var found = new HashSet<string>();
var nonZeroDigits = validInput.Except(new[] { 0 });
var max = int.Parse(string.Join("", nonZeroDigits.OrderByDescending(i => i)));
for (int i = 0; i <= max; i++)
{
var potential = i;
var complements = GetComplements(potential, validInput);
if (complements != null)
{
foreach (var complement in complements)
{
var signature = GetSignature(potential, complement);
if (!found.Contains(signature))
{
found.Add(signature);
yield return Tuple.Create(potential, complement);
}
}
}
}
}
private static string GetSignature(int potential, int complement)
{
// Sort it so we don't get duplicates.
var key = new[] { potential, complement }.OrderBy(i => i).ToArray();
var formatted = string.Format("{0} {1}", key[0], key[1]);
return formatted;
}
private static List<int> GetComplements(int potential, int[] validInput)
{
var remaining = validInput.ToList();
var digits = potential.ToString().Select(c => int.Parse(c.ToString())).ToArray();
foreach (var d in digits)
{
// This means the potential isn't a valid candidate.
if (!remaining.Contains(d))
{
return null;
}
remaining.Remove(d);
}
// This means there were no other digits to choose.
if (remaining.Count == 0)
{
return null;
}
else
{
var complements = new List<int>();
Scramble(complements, "", remaining);
return complements;
}
}
private static void Scramble(List<int> complements, string result, IEnumerable<int> remaining)
{
if (remaining.Any())
{
foreach (var i in remaining)
{
var childResult = result + i;
var childRemaining = remaining.Except(new[] { i });
Scramble(complements, childResult, childRemaining);
}
}
else
{
if (!result.StartsWith("0") || result.Length == 1)
{
var intResult = int.Parse(result);
complements.Add(intResult);
}
}
}
private static int[] ValidateInput(IEnumerable<int> input)
{
// Make sure (2) integers were entered.
if (input == null || input.Count() < 2)
{
// TODO
throw new Exception();
}
// Make sure you don't have duplicates.
var result = input.Distinct().ToArray();
// Make sure the numbers are in range.
if (result.Min() < 0 || result.Max() > 9)
{
// TODO
throw new Exception();
}
return result;
}
}
提示函数可以这样内联。
答案 2 :(得分:2)
这是一个带有可选默认提示的版本:
function read_confirm --description 'Ask the user for confirmation' --argument prompt
if test -z "$prompt"
set prompt "Continue?"
end
while true
read -p 'set_color green; echo -n "$prompt [y/N]: "; set_color normal' -l confirm
switch $confirm
case Y y
return 0
case '' N n
return 1
end
end
end
答案 3 :(得分:1)
要安装两者,只需在鱼壳中
即可curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
. ~/.config/fish/config.fish
fisher get
然后你可以在fish function / script
中写下这样的东西get --prompt="Are you sure [yY]?:" --rule="[yY]" | read confirm
switch $confirm
case Y y
# DELETE COMMAND GOES HERE
end